package com.xxcxcxcx.jobsystem.common.event;

import com.xxcxcxcx.jobsystem.common.Job.Speed.Speed;
import com.xxcxcxcx.jobsystem.common.JobsClass;
import com.xxcxcxcx.jobsystem.common.capability.JobCapability;
import com.xxcxcxcx.jobsystem.common.capability.JobCapabilityProvider;
import com.xxcxcxcx.jobsystem.common.pack.Networking;
import com.xxcxcxcx.jobsystem.packet.ServerLevelPacket;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.LogicalSide;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.network.PacketDistributor;

import static com.xxcxcxcx.jobsystem.common.Job.Endurance.Endurance.Endurances;
import static com.xxcxcxcx.jobsystem.common.Job.MeleeAttack.MeleeAttack.MeleeAttacks;
import static com.xxcxcxcx.jobsystem.common.Job.Speed.Speed.Speeds;

@Mod.EventBusSubscriber
public class JobCommonEventHandler {
    @SubscribeEvent
    public static void onPlayerTick(TickEvent.PlayerTickEvent event) {
        Player player = event.player;
        if(player == null) {
            return;
        }

        //获得经验cd更新
        if(event.phase != TickEvent.Phase.END) {
            return;
        }
        LazyOptional<JobCapability> capability = JobCapabilityProvider.getPlayerData(player);
        capability.ifPresent(i -> i.tickChange());

        if(event.side == LogicalSide.SERVER) {
            serverPlayerTick(player);
        } else {
            capability.ifPresent(i -> updatePlayerAttitude(player, i));
        }
    }

    public static void updatePlayerAttitude(Player player, JobCapability cap) {
        int a = cap.getLevel(JobsClass.Speed);
        int b = cap.getLevel(JobsClass.Endurance);
        int c = cap.getLevel(JobsClass.MeleeAttack);
        for(int i = 0; i < Speeds.length; i++) {
            if(a > i) {
                player.getAttribute(Attributes.MOVEMENT_SPEED).removeModifier(Speeds[i]);
                player.getAttribute(Attributes.MOVEMENT_SPEED).addTransientModifier(Speeds[i]);
            } else {
                player.getAttribute(Attributes.MOVEMENT_SPEED).removeModifier(Speeds[i]);
            }
        }
        for(int i = 0; i < Endurances.length; i++) {
            if(b > i) {
                player.getAttribute(Attributes.MAX_HEALTH).removeModifier(Endurances[i]);
                player.getAttribute(Attributes.MAX_HEALTH).addTransientModifier(Endurances[i]);
            } else {
                player.getAttribute(Attributes.MAX_HEALTH).removeModifier(Endurances[i]);
            }
        }
        for(int i = 0; i < MeleeAttacks.length; i++) {
            if(c > i) {
                player.getAttribute(Attributes.ATTACK_DAMAGE).removeModifier(MeleeAttacks[i]);
                player.getAttribute(Attributes.ATTACK_DAMAGE).addTransientModifier(MeleeAttacks[i]);
            } else {
                player.getAttribute(Attributes.ATTACK_DAMAGE).removeModifier(MeleeAttacks[i]);
            }
        }
    }

    public static void serverPlayerTick(Player player) {
        //速度经验增加
        LazyOptional<JobCapability> capability = JobCapabilityProvider.getPlayerData(player);
        if(!capability.isPresent()) {
            return;
        }
        JobCapability cap = capability.resolve().get();
        if(player.isPassenger()) {
            cap.oldPos = new Vec3(player.position().x, 0, player.position().z);
        }
        if(cap.oldPos == null) {
            cap.speedTime = 100;
            cap.oldPos = new Vec3(player.position().x, 0, player.position().z);
        } else if(cap.speedTime == 0) {
            Vec3 newPos = new Vec3(player.position().x, 0, player.position().z);
            Speed.UpExperienceChange(player, cap.oldPos.distanceTo(newPos) / 10, JobsClass.Speed);
            cap.oldPos = newPos;
            cap.speedTime = 100;
            cap.saveMessage++;
        } else {
            cap.speedTime--;
        }
        if(cap.saveMessage == 12 || cap.canChange()) {
            if(cap.canChange()) {
                //在4,7,10级的时候衰减系数+1
                int num = 0;
                for(int i = 0; i < JobsClass.Jobs.length; i++) {
                    int level = cap.getLevel(JobsClass.Jobs[i]);
                    if(level == 10) {
                        num += 3;cap.setCoefficient(JobsClass.Jobs[i],Math.pow(1.34,3));
                    } else if(level >= 7) {
                        num += 2;cap.setCoefficient(JobsClass.Jobs[i],Math.pow(1.34,2));
                    } else if(level >= 4) {
                        num += 1;cap.setCoefficient(JobsClass.Jobs[i],Math.pow(1.34,1));
                    }else cap.setCoefficient(JobsClass.Jobs[i],1);
                }
                cap.setAttenuationTimes(num);
            }
            cap.setChange(false);
            cap.saveMessage = 0;
            updatePlayerAttitude(player, cap);

            //向客户端发送更新数据包
            if(!cap.getCoefficient().isEmpty())Networking.INSTANCE.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) player), new ServerLevelPacket(player, cap.getLevel(), cap.getExperience(), cap.getCoefficient()));
        }
    }
}
